#include "Mod_ForwardServer.h"
//#include "FlashConfig.h"
#include "stdio.h"
#include "modbus_port.h"

cForwardServer ForwardServer;

// 定义数组（按顺序存放所有宏值）
const uint16_t W5500_SOCKET_REGS[] = {
		W5500_SELECT_SOCKET0_REG,
    W5500_SELECT_SOCKET1_REG,
    W5500_SELECT_SOCKET2_REG,
    W5500_SELECT_SOCKET3_REG,
	  W5500_SELECT_SOCKET4_REG,
    W5500_SELECT_SOCKET5_REG
};


/**
 * 函数功能：cForwardServer构造函数
 * 参    数：无
 * 返 回 值：无
 */
cForwardServer::cForwardServer()
{
    /*设置W5500结构体指针*/
    this->pst_W5500Struct = &gst_W5500_Dev;
	  /*设置uart 结构体指针数组*/
	  this->pUartDevice[0] = &gst_Uart2;
		this->pUartDevice[1] = &gst_Uart3;
		this->pUartDevice[2] = &gst_Uart4;
		this->pUartDevice[3] = &gst_Uart5;
		this->pUartDevice[4] = &gst_Uart6;
		//this->pUartDevice[5] = &gst_Uart6;

	  /*设置串口中断回调函数指针*/
		for (int i = 0; i < UART_PORT_NUM; ++i)
		{
			  this->pst_W5500Struct->st_Socket[i].puch_RxBuff=this->auch_SocketRxBuff[i];
			  this->pst_W5500Struct->st_Socket[i].puin_RxSize=&this->uin_SocketRxSize[i];
			  this->pst_W5500Struct->st_Socket[i].puch_TxBuff=this->auch_SocketTxBuff[i];
			  this->pst_W5500Struct->st_Socket[i].puin_TxSize=&this->uin_SocketTxSize[i];
			  
																												 
				this->pUartDevice[i]->uartIdx = i;
				this->pUartDevice[i]->RxCplCallback = UartRxCplCallback;
				this->pUartDevice[i]->TxCplCallback = UartTxCplCallback;
				this->pUartDevice[i]->ErrorCallback = UartErrorCallback;
			
			  /*数据缓存区清零*/
        memset(this->auch_SocketRxBuff[i], 0, BUF_SIZE);
        memset(this->auch_SocketTxBuff[i], 0, BUF_SIZE);
		}
		
		 
	
}



void cForwardServer::Init(void)
{
	  //重置w5500芯片
    Drv_W5500_Reset(this->pst_W5500Struct);
    /*设置网络配置信息,然后初始化*/
    InitNet();
	  //HAL_Delay(100);
    /*初始化W5500*/
    Drv_W5500_Init(this->pst_W5500Struct);       

    // 初始化串口配置
    InitUart();
	
	  // 初始化串口缓冲区 ,定义结构体和缓存
    InitCircleBuf();

    // 开启串口接收
    //InitSocket();

    printf("ForwardServer Init Done\r\n");
}

//将全局变量赋值到W5500结构体中
void cForwardServer::InitNet(void)
{
	  this->pst_W5500Struct->st_CfgMsg.auch_GA[0] = local_net_config.auch_GA[0];
    this->pst_W5500Struct->st_CfgMsg.auch_GA[1] = local_net_config.auch_GA[1];
    this->pst_W5500Struct->st_CfgMsg.auch_GA[2] = local_net_config.auch_GA[2];
    this->pst_W5500Struct->st_CfgMsg.auch_GA[3] = local_net_config.auch_GA[3];
    this->pst_W5500Struct->st_CfgMsg.auch_SIP[0] = local_net_config.auch_SIP[0];
    this->pst_W5500Struct->st_CfgMsg.auch_SIP[1] = local_net_config.auch_SIP[1];
    this->pst_W5500Struct->st_CfgMsg.auch_SIP[2] = local_net_config.auch_SIP[2];
    this->pst_W5500Struct->st_CfgMsg.auch_SIP[3] = local_net_config.auch_SIP[3];
    this->pst_W5500Struct->st_CfgMsg.auch_SUB[0] = local_net_config.auch_SUB[0];
    this->pst_W5500Struct->st_CfgMsg.auch_SUB[1] = local_net_config.auch_SUB[1];
    this->pst_W5500Struct->st_CfgMsg.auch_SUB[2] = local_net_config.auch_SUB[2];
    this->pst_W5500Struct->st_CfgMsg.auch_SUB[3] = local_net_config.auch_SUB[3];		
		
	   printf("IP Address SetNetconfig: %d.%d.%d.%d\n", 
       pst_W5500Struct->st_CfgMsg.auch_SIP[0],
       pst_W5500Struct->st_CfgMsg.auch_SIP[1],
       pst_W5500Struct->st_CfgMsg.auch_SIP[2],
       pst_W5500Struct->st_CfgMsg.auch_SIP[3]);
}

//将全局变量复制到uart结构体中
void cForwardServer::InitUart(void)
{
    for (int i = 0; i < UART_PORT_NUM; ++i)
    {
//        if (i == DEBUG_UART_INDEX)
//            continue; // 跳过调试口

			  // 将全局配置赋给结构体,串口配置项是从i=0开始，
			  //0作为调试口不进行配置，所以socket0对应pUartDevice[1]
        this->pUartDevice[i]->config = local_uart_config[i+1];
				
//				// ★★★ 打印第4路 UART 的关键配置值 ★★★
//        if (i == 4) {
//            printf("[InitUart] UART%d BaudRate = %u\r\n", i, this->pst_SocketUart[i]->config.BaudRate);
//            printf("[InitUart] UART%d DataBits = %d\r\n", i, this->pst_SocketUart[i]->config.DataBits);
//            printf("[InitUart] UART%d StopBits = %d\r\n", i, this->pst_SocketUart[i]->config.StopBits);
//            printf("[InitUart] UART%d Parity   = %d\r\n", i, this->pst_SocketUart[i]->config.Parity);
//        }
				
				// 写入配置信息
				STM32UartSetConfig(pUartDevice[i]);
				
				//开启串口接收
				STM32UartReceive(pUartDevice[i], 
                         UartRxDMABuf[i], 
                         BUF_SIZE);
    }
}

/**
 * 函数功能：处理网卡和串口互相转发
 * 参    数：无
 * 返 回 值：无
 */
void cForwardServer::Process(void)
{
      this->TCPToUart();
      this->UartToTCP();
	    //this->HeartToSocket();
}

//void cForwardServer::InitSocket(void)
//{
//    LoadSocketConfigFromFlash(); // 读取 6 路 socket 参数

//    for (int i = 0; i < SOCKET_NUM; ++i)
//    {
//        if (pst_SocketUart[i] != nullptr && rx_buff[i] != nullptr)
//        {
//            STM32UartReceive(pst_SocketUart[i], rx_buff[i], BUF_SIZE);
//        }
//    }
//}



void cForwardServer::InitCircleBuf(void)
{
	  //uart环形缓冲区从0-4
    for (int i = 0; i < SOCKET_PORT_NUM; i++)
    {
        circle_buf_init(&UartRxBufCtrl[i], UART_CIRCLE_BUF_LEN, UartRxBufMem[i]);
    }
}

//处理串口数据通过网口发送，前提是socket连接正常
void cForwardServer::UartToTCP(void)
{
		//有关串口数据都是从uart(1-5),所有关于socket都是从0-4
	  for (int uartIdx = 0; uartIdx < SOCKET_PORT_NUM; uartIdx++)  // UART0 ~ UART5
    {
        SendFromRingBuffer(this->pst_W5500Struct,
                           &UartRxBufCtrl[uartIdx],
                           auch_SocketTxBuff[uartIdx],
                           &uin_SocketTxSize[uartIdx],
                           W5500_SOCKET_REGS[uartIdx]);
    } 
}

/**
 * 函数功能：处理向Socket连接发送心跳包
 * 参    数：无
 * 返 回 值：无
 */
void cForwardServer::HeartToSocket(void)
{
	  uint32_t now = HAL_GetTick();  // 获取当前时间（ms）
    
		for (int i = 0; i < SOCKET_PORT_NUM; i++)
    {
        if ((now - lastHeartbeatTick_Socket[i]) >= SOCK_RECONNECT_TIMEOUT)
        {
            Drv_W5500_TCPSend(this->pst_W5500Struct, W5500_SOCKET_REGS[i]);
            lastHeartbeatTick_Socket[i] = now;
        }
    }
		
}

/**
 * 函数功能： 从环形缓冲区取出数据并发送到网络
 * 参    数： pst_W5500Struct 网口结构体
 *           p_RingBuf 环形缓冲区
 *           p_TxBuff 发送缓冲区
 *           p_TxSize 发送字节数地址
 *           uch_SocketReg 选择的socket
 * 返 回 值：无
 */
void SendFromRingBuffer(W5500_TypeDef *pst_W5500Struct,
                                  circle_buf *p_RingBuf,
                                  uint8_t *p_TxBuff,
                                  uint16_t *p_TxSize,
                                  uint8_t uch_SocketReg)
{
    uint8_t *txBuffPtr = p_TxBuff; // 指针指向缓冲区起始地址
    *p_TxSize = 0;

    // 从环形缓冲区读取数据到发送缓冲区
    while (circle_buf_read(p_RingBuf, txBuffPtr) == 0)
    {
        txBuffPtr++;
        (*p_TxSize)++;
    }

    // 如果有数据要发送
    if (*p_TxSize > 0)
    {
			  //printf("Sending data on socket %d, size = %d\n", uch_SocketReg>>2, *p_TxSize);
        Drv_W5500_TCPSend(pst_W5500Struct, uch_SocketReg);
        *p_TxSize = 0;
    }
}


/**
 * 函数功能：串口接收完成中断回调函数
 * 参    数：pst_UartStruct 串口结构体
 *           uin_Size 接收字节数
 * 返 回 值：无
 */
void UartRxCplCallback(struct _Uart_TypeDef *pst_UartStruct, uint16_t uin_Size)
{
		int uartIdx = pst_UartStruct->uartIdx;

    // 索引有效性验证（防止越界和结构体不一致的风险）
    if (uartIdx < 0 || uartIdx >= UART_PORT_NUM || 
        ForwardServer.pUartDevice[uartIdx] != pst_UartStruct)
    {
        printf("UartRxCplCallback error: invalid uartIdx=%d or mismatch\n", uartIdx);
        return;
    }
    
    // 检查索引有效性
    if ((uartIdx < 0) || (uartIdx >= UART_PORT_NUM) || 
        (ForwardServer.pUartDevice[uartIdx] != pst_UartStruct)) {
        return;
    }
				
		// 打印调试信息：哪个串口收到了多少字节
    //printf("UART[%d] Received %d bytes, struct ptr = %p\n", uartIdx, uin_Size, (void *)pst_UartStruct);

    // 写入接收缓冲区
    for (uint16_t i = 0; i < uin_Size; ++i)
    {
			  //printf("start write circle,the  %u time val is %c.!\n",i,ForwardServer.UartRxDMABuf[uartIdx][i]);
        if (circle_buf_write(&ForwardServer.UartRxBufCtrl[uartIdx], ForwardServer.UartRxDMABuf[uartIdx][i]) != 0)
        {
            printf("UART[%d] Write failed at index %u with value 0x%02X\n",
                   uartIdx, i, ForwardServer.UartRxDMABuf[uartIdx][i]);
        }
    }
    
		//开启串口接收
		STM32UartReceive(ForwardServer.pUartDevice[uartIdx], 
                     ForwardServer.UartRxDMABuf[uartIdx], 
                     BUF_SIZE);

}

/**
 * 函数功能：串口发送完成中断回调函数
 * 参    数：pst_UartStruct 串口结构体
 *           uin_Size 接收字节数
 * 返 回 值：无
 */
void UartTxCplCallback(struct _Uart_TypeDef *pst_UartStruct)
{
		int uartIdx = pst_UartStruct->uartIdx;
	  if (uartIdx >= UART_PORT_NUM || ForwardServer.pUartDevice[uartIdx] != pst_UartStruct)
    {
        printf("TxCplCallback error: invalid index or mismatch\n");
        return;
    }     
    // 如果配置了 RS485 DE 引脚
    if (pst_UartStruct->pst_DEPort != NULL)
    {
			
        HAL_GPIO_WritePin(
            pst_UartStruct->pst_DEPort,
            pst_UartStruct->ul_DEPin,
            GPIO_PIN_RESET);

        //printf("UART[%d] DE set LOW (TX completed)\n", uartIdx);
    }

   
}


/**
 * 函数功能：串口错误中断回调函数
 * 参    数：pst_UartStruct 串口结构体
 * 返 回 值：无
 */
void UartErrorCallback(struct _Uart_TypeDef *pst_UartStruct)
{
	  int uartIdx = pst_UartStruct->uartIdx;
    
    // 检查索引有效性
    if (uartIdx < 0 || uartIdx >= UART_PORT_NUM || 
        ForwardServer.pUartDevice[uartIdx] != pst_UartStruct)
    {
        printf("UartErrorCallback error: invalid uartIdx=%d or mismatch\n", uartIdx);
        return;
    }
		
    if (pst_UartStruct == ForwardServer.pUartDevice[uartIdx])
    {
        /*重新开启串口接收*/
			  //printf("UartErrorCallback start receive: uartIdx=%d or mismatch\n", uartIdx);
        STM32UartReceive(ForwardServer.pUartDevice[uartIdx], ForwardServer.UartRxDMABuf[uartIdx], BUF_SIZE);
    }

}
/**
 * 函数功能：处理网口数据通过串口转发
 * 参    数：无
 * 返 回 值：无
 */
void cForwardServer::TCPToUart(void)
{
    uint8_t auch_RecvFlag[SOCKET_PORT_NUM]={0};    
   
		int validSocketList[SOCKET_PORT_NUM] = {0};  // 存储需要处理的 socket
    int validSocketCount = 0;

    /*TCP服务端处理*/
    //Drv_TCPServer(this->pst_W5500Struct, W5500_SELECT_SOCKET0_REG);
    //    Drv_TCPServer(this->pst_W5500Struct, W5500_SELECT_SOCKET1_REG);
    //    Drv_TCPServer(this->pst_W5500Struct, W5500_SELECT_SOCKET2_REG);
    //    Drv_TCPServer(this->pst_W5500Struct, W5500_SELECT_SOCKET3_REG);

    // TCP客户端处理
    // Drv_TCPClient(this->pst_W5500Struct, W5500_SELECT_SOCKET0_REG);
    // Drv_TCPClient(this->pst_W5500Struct, W5500_SELECT_SOCKET1_REG);
    // Drv_TCPClient(this->pst_W5500Struct, W5500_SELECT_SOCKET2_REG,serverIP,40001) ;
		
	  for (int i = 0; i < SOCKET_PORT_NUM; ++i)
    {  		
		    
				
				// 特殊处理 Socket5（用于 IO 控制）--改到modbus中去了
				//if (i == 5 && auch_RecvFlag[5] && uin_SocketRxSize[5] > 0)
			  if (i == 5)
				{					
						Drv_TCPServer(this->pst_W5500Struct, W5500_SELECT_SOCKET5_REG);
						//TCP_ProcessCommand(auch_SocketRxBuff[5], uin_SocketRxSize[5]);
						//Drv_W5500_ClearRecvFlag(this->pst_W5500Struct, W5500_SOCKET_REGS[5]);
					  auch_RecvFlag[5] = Drv_W5500_GetRecvFlag(this->pst_W5500Struct, W5500_SOCKET_REGS[5]);
					
					  // 特殊处理 Socket5和RecvFlag[5]
						if (auch_RecvFlag[5]!=false)
						{
							
							  uint8_t* pBuff = this->pst_W5500Struct->st_Socket[i].puch_RxBuff;
                uint16_t len = uin_SocketRxSize[i];  // 实际接收到的长度
								//printf("[W550]socket5 receive Buffer (%d bytes): ", len);
//								for (uint16_t j = 0; j < len; j++)
//								{
//										printf("%02X ", pBuff[j]);
//								}
//								printf("\n");
								ModbusPort_SetRxData(pBuff ,len); // ⬅️ 传递给 modbus_port 层
								Drv_W5500_ClearRecvFlag(this->pst_W5500Struct, W5500_SOCKET_REGS[5]);
								break;  // 跳过后续的串口转发逻辑
						}	
						break;
				}
				
				//socket_client连接5个通道0-4
				Drv_TCPClient(this->pst_W5500Struct,W5500_SOCKET_REGS[i],
								local_socket_config[i].server_ip,
								local_socket_config[i].server_port);
				

				auch_RecvFlag[i] = Drv_W5500_GetRecvFlag(this->pst_W5500Struct, W5500_SOCKET_REGS[i]);           		
				
				// 其余 Socket 对应的 UART 转发
				//if (auch_RecvFlag[i] || uin_SocketRxSize[i] > 0)
				if (auch_RecvFlag[i]!=false)
				{
						int uart_index = i;  // UART 从 0 开始对齐 Socket0~4
			
  					STM32UartTransmit(this->pUartDevice[uart_index],auch_SocketRxBuff[i],uin_SocketRxSize[i]);
						//printf("uart send  Buffer is %s\n", auch_SocketRxBuff[i]);
						//printf("uart send  Buffer size is %d\n", uin_SocketRxSize[i]);
						Drv_W5500_ClearRecvFlag(this->pst_W5500Struct, W5500_SOCKET_REGS[i]);	
			  }				

		}


}




/**
 * 函数功能：解析TCP数据控制GPIO
 * 参    数：接收数据和长度
 * 返 回 值：无
 */
void TCP_ProcessCommand(uint8_t *rxBuffer, uint16_t len)
{
    printf("TCP_ProcessCommand Buffer is %s\n", rxBuffer);

    if (memcmp(rxBuffer, "ON1", 3) == 0)  // 控制 GPIO1 高电平
    {
        printf("PWM1 is %s\n", rxBuffer);
        //HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, GPIO_PIN_SET);.
				HAL_GPIO_WritePin(DO0_GPIO_Port, DO0_Pin, GPIO_PIN_SET);
    }
    else if (memcmp(rxBuffer, "OFF1", 4) == 0)  // 控制 GPIO1 低电平
    {   printf("PWM1 is %s\n", rxBuffer);
        HAL_GPIO_WritePin(DO0_GPIO_Port, DO0_Pin, GPIO_PIN_RESET);
    }         
		else if (memcmp(rxBuffer, "ON2", 3) == 0)  // 控制 GPIO1 高电平
    {
        printf("PWM2 is %s\n", rxBuffer);
        HAL_GPIO_WritePin(DO1_GPIO_Port, DO1_Pin, GPIO_PIN_SET);
    }
    else if (memcmp(rxBuffer, "OFF2", 4) == 0)  // 控制 GPIO1 低电平
    {
			  printf("PWM2 is %s\n", rxBuffer);
        HAL_GPIO_WritePin(DO1_GPIO_Port, DO1_Pin, GPIO_PIN_RESET);
    }
		else if (memcmp(rxBuffer, "ON3", 3) == 0)  // 控制 GPIO1 高电平
    {
        printf("PWM2 is %s\n", rxBuffer);
        HAL_GPIO_WritePin(DO2_GPIO_Port, DO2_Pin, GPIO_PIN_SET);
    }
    else if (memcmp(rxBuffer, "OFF3", 4) == 0)  // 控制 GPIO1 低电平
    {
			  printf("PWM2 is %s\n", rxBuffer);
        HAL_GPIO_WritePin(DO2_GPIO_Port, DO2_Pin, GPIO_PIN_RESET);
    }
}
